/**
 * ...
 * >author		João Vítor de Souza
 */

package com.cupcakeengine.core 
{
	import com.cupcakeengine.events.EventBroadcaster;
	import com.cupcakeengine.events.LoopManagerEvent;
	import flash.display.Sprite;
	import flash.events.Event;	
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;

	public class LoopManager 
	{
		// ___________________________________________________________________ CONSTANTS		
		
		// ___________________________________________________________________ CLASS PROPERTIES
		
		private var _dUpdate											: Dictionary;
		private var _dUpdatePause										: Dictionary;
		private var _running											: Boolean = false;
		
		// ___________________________________________________________________ INSTANCE PROPERTIES
		
		private static var _instance									: LoopManager;
		private var _root												: Sprite;
		private var _timer												: Timer;
		
		
		
		// ___________________________________________________________________ GETTERS AND SETTERS		
		
		// ___________________________________________________________________ CONSTRUCTOR
		
		public function LoopManager (singleton:SingletonObligate) {}
		
		// ___________________________________________________________________ PUBLIC METHODS
		
		public static function getInstance () : LoopManager
		{
			if (!LoopManager._instance) LoopManager._instance = new LoopManager(new SingletonObligate());
			return LoopManager(LoopManager._instance);
		}
		
		public function start(root:Sprite):void
		{
			if (_running) return;			
			_running = true;		
			
			_root = root;			
			_root.addEventListener(Event.ENTER_FRAME, oef);
			//_timer = new Timer(1 / 30);
			//_timer.addEventListener(TimerEvent.TIMER, oef);
			//_timer.start();
			
			EventBroadcaster.broadcastEvent(new LoopManagerEvent(LoopManagerEvent.START));
		}
		
		public function stop():void
		{			
			if (!_running) return;
			
			_root.removeEventListener(Event.ENTER_FRAME, oef);
			//_timer.removeEventListener(TimerEvent.TIMER, oef);
			//_timer.stop();
			
			EventBroadcaster.broadcastEvent(new LoopManagerEvent(LoopManagerEvent.STOP));
		}
		
		public function add(update:IUpdatable, id:String = "default"):void
		{
			if (_dUpdate == null) _dUpdate = new Dictionary();			
			
			var v:Vector.<IUpdatable> = _dUpdate[id];
			if (v == null) v = new Vector.<IUpdatable>;
			
			v.push(update);
			_dUpdate[id] = v;
		}
		
		public function remove(update:IUpdatable, id:String = "default"):void
		{
			if (_dUpdate == null) return;
			if (_dUpdate[id] == null) return;
			
			var v:Vector.<IUpdatable> = _dUpdate[id];
			if (v.indexOf(update) == -1) return;
			
			v.splice(v.indexOf(update), 1);
			_dUpdate[id] = v;
		}
		
		public function pause(id:String = "default"):void
		{
			if (_dUpdatePause == null) _dUpdatePause = new Dictionary();
			
			_dUpdatePause[id] = _dUpdate[id];
			_dUpdate[id] =  null;
		}
		
		public function resume(id:String = "default"):void
		{
			if (_dUpdatePause == null) return;
			
			_dUpdate[id] = _dUpdatePause[id];
			_dUpdatePause[id];
		}
		
		// ___________________________________________________________________ PRIVATE METHODS
		
		// ___________________________________________________________________ EVENTS
		
		private function oef(e:Event):void 
		{			
			for each(var v:Vector.<IUpdatable> in _dUpdate){
				for each(var u:IUpdatable in v) {
					u.update();
				}
			}
		}	
	}
}

class SingletonObligate {}